﻿using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Data;
//using System.Data.Entity.Infrastructure.DbSqlQuery;


namespace RMS.Models.Repository
{
    /* Repository class acts as a bridge between the web application and database. */

    public class Repository {
        private EFDbContext context = new EFDbContext();

        // The Repository class defines a property called Retreats, 
        // which returns results of reading the property of the same name from the EFDbContext class.
        public IEnumerable<Retreat> Retreats {
            get { return context.Retreats; }
        }

        public IEnumerable<User> Users
        {
            get { return context.Users; }
        }

        public Retreat GetRetreat(int retID)
        {
            return context.Retreats.Find(retID);
        }
        
        // Method for adding a retreat to database.
        public void SaveRetreat(Retreat retreat)
        {
            /* We identify Retreat objects for which there is no corresponding row in the database by looking for zero Ret_ID values. 
             * If a Retreat object has a non-zero Ret_ID, then we update the existing data we have stored in the database. */
            if (retreat.Ret_ID == 0)
            {
                retreat = context.Retreats.Add(retreat);
            }
            else
            {
                Retreat dbRetreat = context.Retreats.Find(retreat.Ret_ID);
                if (dbRetreat != null)
                {
                    dbRetreat.Ret_Title = retreat.Ret_Title;
                    dbRetreat.Ret_Presenters = retreat.Ret_Presenters;
                    dbRetreat.Ret_Dates = retreat.Ret_Dates;
                    dbRetreat.Ret_Checkin = retreat.Ret_Checkin;
                    dbRetreat.Ret_About = retreat.Ret_About;
                    dbRetreat.Ret_Cost = retreat.Ret_Cost;
                    dbRetreat.Ret_Main_Category = retreat.Ret_Main_Category;
                    dbRetreat.Ret_Category_Two = retreat.Ret_Category_Two;
                    dbRetreat.Ret_Category_Three = retreat.Ret_Category_Three;
                    dbRetreat.Ret_Category_Four = retreat.Ret_Category_Four;
                    dbRetreat.Ret_Length = retreat.Ret_Length;
                                  
                }
            }
            context.SaveChanges();
        }
        
        // Method for deleting a retreat from database
        public void DeleteRetreat(Retreat retreat)
        {
            IEnumerable<Reservation> reservations = context.Reservations
            .Include(o => o.OrderLines.Select(ol => ol.Retreat))
            .Where(o => o.OrderLines.Count(ol => ol.Retreat
            .Ret_ID == retreat.Ret_ID) > 0).ToArray();
            foreach (Reservation reservation in reservations)
            {
                context.Reservations.Remove(reservation);
            }
            context.Retreats.Remove(retreat);
            context.SaveChanges();
        }
       

        public IEnumerable<Reservation> Reservations 
        {
            get
            {
                return context.Reservations.Include(o => o.OrderLines.Select(ol => ol.Retreat));
            }
        }

        // Method for adding a reservation to the database.
        public void SaveReservation(Reservation order)
        {
            if (order.ResId == 0)
            {
                order = context.Reservations.Add(order);

                foreach (OrderLine line in order.OrderLines)
                {
                    context.Entry(line.Retreat).State = System.Data.Entity.EntityState.Modified;
                }

            }
            else
            {
                Reservation dbReservation = context.Reservations.Find(order.ResId);
                if (dbReservation != null)
                {
                    dbReservation.Res_Fname = order.Res_Fname;
                    dbReservation.Res_Address = order.Res_Address;
                    dbReservation.Res_Lname = order.Res_Lname;
                    dbReservation.Res_City = order.Res_City;
                    dbReservation.Res_State = order.Res_State;
                    dbReservation.Res_Zipcode = order.Res_Zipcode;
                    dbReservation.Res_Phone = order.Res_Phone;
                    dbReservation.Res_Email = order.Res_Email;
                    dbReservation.Res_Chosen_Date = order.Res_Chosen_Date;
                    dbReservation.Res_Issue_Date = order.Res_Issue_Date;
                    dbReservation.Res_First_Floor = order.Res_First_Floor;
                    dbReservation.Res_Diet_Needs = order.Res_Diet_Needs;
                    dbReservation.Res_Multiple_Guests = order.Res_Multiple_Guests;
                    dbReservation.Res_Guest_Info = order.Res_Guest_Info;
                    dbReservation.Res_Pay_Check = order.Res_Pay_Check;
                    dbReservation.Res_Pay_Credit = order.Res_Pay_Credit;
                    dbReservation.Res_RetID = order.Res_RetID;
                    //dbReservation.User = user;
                
                }
            }
            
            context.SaveChanges();
        }

        public void DeleteReservation(Reservation res)
        {
            /*
             * Joe's Old Code (keep for now)
            OrderLine olToDelete = null;
            foreach(OrderLine ol in res.OrderLines)
            {
               // ol = res.OrderLines.Where(o => res.OrderLines == res)
                if (ol.Reservation.ResId == res.ResId)
                    olToDelete = ol;
            }

            if(olToDelete != null)
                res.OrderLines.Remove(olToDelete);
           context.Reservations.Remove(res);
           */

            IEnumerable<OrderLine> lines = context.OrderLines;

            foreach (OrderLine ol in lines)
            {
                if (ol.Reservation.ResId == res.ResId)
                {
                    context.OrderLines.Remove(ol);
                }
            }

            context.Reservations.Remove(res);
            context.SaveChanges();
        }

        // VolunteerItems Related Methods
        public IEnumerable<VolunteerItem> VolunteerItems {
            get { return context.VolunteerItems; }
        }

        public void SaveVolunteerItem(VolunteerItem volunteerItem)
        {

            if (volunteerItem.VolunteerItemId == 0)
            {
                volunteerItem = context.VolunteerItems.Add(volunteerItem);
            }
            else
            {
                VolunteerItem dbVolunteerItem = context.VolunteerItems.Find(volunteerItem.VolunteerItemId);
                if (dbVolunteerItem != null) 
                {
                    dbVolunteerItem.VolunteerItemType = volunteerItem.VolunteerItemType;
                    dbVolunteerItem.VolunteerItemCategory = volunteerItem.VolunteerItemCategory;
                    dbVolunteerItem.User_Us_ID = volunteerItem.User_Us_ID;
                }
            }
            context.SaveChanges();
        }

        public void DeleteVolunteerItem(VolunteerItem vItem)
        {
                      
            context.VolunteerItems.Remove(vItem);
            context.SaveChanges();
        }
       

    }
}